Clean up xenoprof code a bit. The main remaining TODO is to
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Fri, 7 Apr 2006 10:00:28 +0000 (11:00 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Fri, 7 Apr 2006 10:00:28 +0000 (11:00 +0100)
clean up the xenoprof hypercall interface.

Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.6-xen-sparse/arch/i386/oprofile/Makefile
linux-2.6-xen-sparse/arch/x86_64/oprofile/Makefile
xen/arch/x86/domain.c
xen/arch/x86/oprofile/nmi_int.c
xen/arch/x86/oprofile/xenoprof.c
xen/common/event_channel.c
xen/include/public/xen.h
xen/include/public/xenoprof.h
xen/include/xen/sched.h
xen/include/xen/xenoprof.h

index d283cd6c4d483fc4b53c3a04718fbefb88d0ba18..e596c39c09632cfaf7d6bb6e5259b849a6714fb0 100644 (file)
@@ -6,7 +6,7 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
                oprofilefs.o oprofile_stats.o  \
                timer_int.o )
 
-ifdef CONFIG_X86_XEN
+ifdef CONFIG_XEN
 oprofile-y                             := $(DRIVER_OBJS) xenoprof.o
 else 
 oprofile-y                             := $(DRIVER_OBJS) init.o backtrace.o
index 2f9d03b30d943dcf3f62e682f99346b6ab7eea25..589a7966e822de1f4efca113633616f692564ed6 100644 (file)
@@ -11,7 +11,7 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
        oprofilefs.o oprofile_stats.o \
        timer_int.o )
 
-ifdef
+ifdef CONFIG_XEN
 OPROFILE-y := xenoprof.o
 else
 OPROFILE-y := init.o backtrace.o
index 8c0bb136fa42dda6584beb9f5cf16e3ca5b6b57b..a657fba2eb9b8ca77e211bcc3fb6a5b45b6be82d 100644 (file)
@@ -915,8 +915,6 @@ static void relinquish_memory(struct domain *d, struct list_head *list)
     spin_unlock_recursive(&d->page_alloc_lock);
 }
 
-extern void free_xenoprof_pages(struct domain *d);
-
 void domain_relinquish_resources(struct domain *d)
 {
     struct vcpu *v;
index d9495b056619db7085f660e1757dcc24b60a0541..3978428a32995ce89595801d6409415d198e2cfb 100644 (file)
@@ -45,31 +45,23 @@ extern size_t strlcpy(char *dest, const char *src, size_t size);
 
 int nmi_callback(struct cpu_user_regs *regs, int cpu)
 {
-       int xen_mode = 0;
-       int ovf;
+       int xen_mode, ovf;
 
        ovf = model->check_ctrs(cpu, &cpu_msrs[cpu], regs);
        xen_mode = ring_0(regs);
-       if ( ovf )
-       {
-               if ( is_active(current->domain) )
-               {
-                       if ( !xen_mode )
-                       {
-                               send_guest_vcpu_virq(current, VIRQ_XENOPROF);
-                       } 
-               }
-       }
+       if ( ovf && is_active(current->domain) && !xen_mode )
+               send_guest_vcpu_virq(current, VIRQ_XENOPROF);
+
        return 1;
 }
  
  
-static void nmi_cpu_save_registers(struct op_msrs * msrs)
+static void nmi_cpu_save_registers(struct op_msrs *msrs)
 {
        unsigned int const nr_ctrs = model->num_counters;
        unsigned int const nr_ctrls = model->num_controls; 
-       struct op_msr * counters = msrs->counters;
-       struct op_msr * controls = msrs->controls;
+       struct op_msr *counters = msrs->counters;
+       struct op_msr *controls = msrs->controls;
        unsigned int i;
 
        for (i = 0; i < nr_ctrs; ++i) {
index 529c67b601139d8ae329b1d13d6f1e1dc9b6a485..ecd9abd2cf026b3af577aa506ca938d77d834809 100644 (file)
 
 int active_domains[MAX_OPROF_DOMAINS];
 int active_ready[MAX_OPROF_DOMAINS];
-unsigned int adomains = 0;
-unsigned int activated = 0;
-struct domain *primary_profiler = NULL;
+unsigned int adomains;
+unsigned int activated;
+struct domain *primary_profiler;
 int xenoprof_state = XENOPROF_IDLE;
 
-u64 total_samples = 0;
-u64 invalid_buffer_samples = 0;
-u64 corrupted_buffer_samples = 0;
-u64 lost_samples = 0;
-u64 active_samples = 0;
-u64 idle_samples = 0;
-u64 others_samples = 0;
+u64 total_samples;
+u64 invalid_buffer_samples;
+u64 corrupted_buffer_samples;
+u64 lost_samples;
+u64 active_samples;
+u64 idle_samples;
+u64 others_samples;
 
 
 extern int nmi_init(int *num_events, int *is_primary, char *cpu_type);
@@ -39,16 +39,8 @@ extern void nmi_release_counters(void);
 
 int is_active(struct domain *d)
 {
-    xenoprof_t *x = d->xenoprof;
-    if ( x )
-    {
-        if ( x->domain_type == XENOPROF_DOMAIN_ACTIVE )
-            return 1;
-        else
-            return 0;
-    }
-    else
-        return 0;
+    struct xenoprof *x = d->xenoprof;
+    return ((x != NULL) && (x->domain_type == XENOPROF_DOMAIN_ACTIVE));
 }
 
 int is_profiled(struct domain *d)
@@ -65,25 +57,24 @@ static void xenoprof_reset_stat(void)
     active_samples = 0;
     idle_samples = 0;
     others_samples = 0;
-
-    return;
 }
 
 static void xenoprof_reset_buf(struct domain *d)
 {
     int j;
-    xenoprof_buf_t *buf;
+    struct xenoprof_buf *buf;
 
-    if ( !d->xenoprof )
+    if ( d->xenoprof == NULL )
     {
-        printk("xenoprof_reset_buf: ERROR - Unexpected Xenoprof NULL pointer \n");
+        printk("xenoprof_reset_buf: ERROR - Unexpected "
+               "Xenoprof NULL pointer \n");
         return;
     }
 
-    for ( j=0; j<MAX_VIRT_CPUS; j++ )
+    for ( j = 0; j < MAX_VIRT_CPUS; j++ )
     {
         buf = d->xenoprof->vcpu[j].buffer;
-        if ( buf )
+        if ( buf != NULL )
         {
             buf->event_head = 0;
             buf->event_tail = 0;
@@ -93,62 +84,57 @@ static void xenoprof_reset_buf(struct domain *d)
 
 int active_index(struct domain *d)
 {
-    int i;
-    int id;
+    int i, id = d->domain_id;
 
-    id = d->domain_id;
-    for ( i=0; i<adomains; i++ )
+    for ( i = 0; i < adomains; i++ )
         if ( active_domains[i] == id )
-        {
             return i;
-        }
+
     return -1;
 }
 
 int set_active(struct domain *d)
 {
     int ind;
-    xenoprof_t *x;
+    struct xenoprof *x;
 
     ind = active_index(d);
-    if ( ind <0 )
+    if ( ind < 0 )
         return -EPERM;
 
     x = d->xenoprof;
-    if ( x )
-    {
-        x->domain_ready = 1;
-        x->domain_type = XENOPROF_DOMAIN_ACTIVE;
-        active_ready[ind] = 1;
-        activated++;
-        return 0;
-    }
-    else
+    if ( x == NULL )
         return -EPERM;
+
+    x->domain_ready = 1;
+    x->domain_type = XENOPROF_DOMAIN_ACTIVE;
+    active_ready[ind] = 1;
+    activated++;
+
+    return 0;
 }
 
 int reset_active(struct domain *d)
 {
     int ind;
-    xenoprof_t *x;
+    struct xenoprof *x;
 
     ind = active_index(d);
-    if ( ind <0 )
+    if ( ind < 0 )
         return -EPERM;
 
     x = d->xenoprof;
-    if ( x )
-    {
-        x->domain_ready = 0;
-        x->domain_type = XENOPROF_DOMAIN_IGNORED;
-        active_ready[ind] = 0;
-        activated--;
-        if ( activated <= 0 )
-            adomains = 0;
-        return 0;
-    }
-    else
+    if ( x == NULL )
         return -EPERM;
+
+    x->domain_ready = 0;
+    x->domain_type = XENOPROF_DOMAIN_IGNORED;
+    active_ready[ind] = 0;
+    activated--;
+    if ( activated <= 0 )
+        adomains = 0;
+
+    return 0;
 }
 
 int set_active_domains(int num)
@@ -157,13 +143,13 @@ int set_active_domains(int num)
     int i;
     struct domain *d;
 
-    /* reset any existing active domains from previous runs */
-    for ( i=0; i<adomains; i++ )
+    /* Reset any existing active domains from previous runs. */
+    for ( i = 0; i < adomains; i++ )
     {
         if ( active_ready[i] )
         {
             d = find_domain_by_id(active_domains[i]);
-            if ( d )
+            if ( d != NULL )
             {
                 reset_active(d);
                 put_domain(d);
@@ -171,37 +157,33 @@ int set_active_domains(int num)
         }
     }
 
-    adomains=num;
+    adomains = num;
 
     /* Add primary profiler to list of active domains if not there yet */
     primary = active_index(primary_profiler);
     if ( primary == -1 )
     {
-        /* return if there is no space left on list */
+        /* Return if there is no space left on list. */
         if ( num >= MAX_OPROF_DOMAINS )
             return -E2BIG;
-        else
-        {
-            active_domains[num] = primary_profiler->domain_id;
-            num++;
-        }
+        active_domains[num] = primary_profiler->domain_id;
+        num++;
     }
 
     adomains = num;
     activated = 0;
 
-    for ( i=0; i<adomains; i++ )
-    {
+    for ( i = 0; i < adomains; i++ )
         active_ready[i] = 0;
-    }
 
     return 0;
 }
 
-void xenoprof_log_event(struct vcpu *vcpu, unsigned long eip, int mode, int event)
+void xenoprof_log_event(
+    struct vcpu *vcpu, unsigned long eip, int mode, int event)
 {
-    xenoprof_vcpu_t *v;
-    xenoprof_buf_t *buf;
+    struct xenoprof_vcpu *v;
+    struct xenoprof_buf *buf;
     int head;
     int tail;
     int size;
@@ -213,14 +195,14 @@ void xenoprof_log_event(struct vcpu *vcpu, unsigned long eip, int mode, int even
     /* Count samples in idle separate from other unmonitored domains */
     if ( !is_profiled(vcpu->domain) )
     {
-      others_samples++;
-      return;
+        others_samples++;
+        return;
     }
 
     v = &vcpu->domain->xenoprof->vcpu[vcpu->vcpu_id];
 
     /* Sanity check. Should never happen */ 
-    if ( !v->buffer )
+    if ( v->buffer == NULL )
     {
         invalid_buffer_samples++;
         return;
@@ -269,20 +251,19 @@ char *alloc_xenoprof_buf(struct domain *d, int npages)
     int i, order;
 
     /* allocate pages to store sample buffer shared with domain */
-    order = get_order_from_pages(npages);
-    rawbuf =  alloc_xenheap_pages(order);
-    if( rawbuf == NULL )
+    order  = get_order_from_pages(npages);
+    rawbuf = alloc_xenheap_pages(order);
+    if ( rawbuf == NULL )
     {
         printk("alloc_xenoprof_buf(): memory allocation failed\n");
         return 0;
     }
 
     /* Share pages so that kernel can map it */
-    for ( i=0; i<npages; i++ )
-    {
-        share_xen_page_with_guest(virt_to_page(rawbuf + i * PAGE_SIZE), 
-                                 d, XENSHARE_writable);
-    }
+    for ( i = 0; i < npages; i++ )
+        share_xen_page_with_guest(
+            virt_to_page(rawbuf + i * PAGE_SIZE), 
+            d, XENSHARE_writable);
 
     return rawbuf;
 }
@@ -293,9 +274,9 @@ int alloc_xenoprof_struct(struct domain *d, int max_samples)
     int nvcpu, npages, bufsize, max_bufsize;
     int i;
 
-    d->xenoprof = xmalloc(xenoprof_t);
+    d->xenoprof = xmalloc(struct xenoprof);
 
-    if ( !d->xenoprof )
+    if ( d->xenoprof == NULL )
     {
         printk ("alloc_xenoprof_struct(): memory "
                 "allocation (xmalloc) failed\n");
@@ -305,23 +286,23 @@ int alloc_xenoprof_struct(struct domain *d, int max_samples)
     memset(d->xenoprof, 0, sizeof(*d->xenoprof));
 
     nvcpu = 0;
-    for_each_vcpu(d, v)
+    for_each_vcpu ( d, v )
         nvcpu++;
 
     /* reduce buffer size if necessary to limit pages allocated */
-    bufsize = sizeof(xenoprof_buf_t) +
+    bufsize = sizeof(struct xenoprof_buf) +
         (max_samples - 1) * sizeof(struct event_log);
     max_bufsize = (MAX_OPROF_SHARED_PAGES * PAGE_SIZE) / nvcpu;
     if ( bufsize > max_bufsize )
     {
         bufsize = max_bufsize;
-        max_samples = ( (max_bufsize - sizeof(xenoprof_buf_t)) /
+        max_samples = ( (max_bufsize - sizeof(struct xenoprof_buf)) /
                         sizeof(struct event_log) ) + 1;
     }
 
     npages = (nvcpu * bufsize - 1) / PAGE_SIZE + 1;
     d->xenoprof->rawbuf = alloc_xenoprof_buf(d, npages);
-    if ( !d->xenoprof->rawbuf )
+    if ( d->xenoprof->rawbuf == NULL )
     {
         xfree(d->xenoprof);
         d->xenoprof = NULL;
@@ -335,12 +316,12 @@ int alloc_xenoprof_struct(struct domain *d, int max_samples)
     d->xenoprof->domain_type = XENOPROF_DOMAIN_IGNORED;
 
     /* Update buffer pointers for active vcpus */
-    i=0;
-    for_each_vcpu(d, v)
+    i = 0;
+    for_each_vcpu ( d, v )
     {
         d->xenoprof->vcpu[v->vcpu_id].event_size = max_samples;
         d->xenoprof->vcpu[v->vcpu_id].buffer =
-            (xenoprof_buf_t *)&d->xenoprof->rawbuf[i * bufsize];
+            (struct xenoprof_buf *)&d->xenoprof->rawbuf[i * bufsize];
         d->xenoprof->vcpu[v->vcpu_id].buffer->event_size = max_samples;
         d->xenoprof->vcpu[v->vcpu_id].buffer->vcpu_id = v->vcpu_id;
 
@@ -355,21 +336,21 @@ int alloc_xenoprof_struct(struct domain *d, int max_samples)
 
 void free_xenoprof_pages(struct domain *d)
 {
-    xenoprof_t *x;
+    struct xenoprof *x;
     int order;
 
     x = d->xenoprof;
+    if ( x == NULL )
+        return;
 
-    if ( x )
+    if ( x->rawbuf != NULL )
     {
-        if ( x->rawbuf )
-        {
-            order = get_order_from_pages(x->npages);
-            free_xenheap_pages(x->rawbuf, order);
-        }
-        xfree(x);
-        d->xenoprof = NULL;
+        order = get_order_from_pages(x->npages);
+        free_xenheap_pages(x->rawbuf, order);
     }
+
+    xfree(x);
+    d->xenoprof = NULL;
 }
 
 int xenoprof_init(int max_samples, xenoprof_init_result_t *init_result)
@@ -386,13 +367,13 @@ int xenoprof_init(int max_samples, xenoprof_init_result_t *init_result)
     if ( ret < 0 )
         goto err;
 
-    /* we allocate xenoprof struct and buffers only at first time 
-       xenoprof_init is called. Memory is then kept until domain is destroyed */
-    if ( !d->xenoprof )
-    {
-        if ( (ret = alloc_xenoprof_struct(d, max_samples)) < 0 )
-            goto err;
-    }
+    /*
+     * We allocate xenoprof struct and buffers only at first time xenoprof_init
+     * is called. Memory is then kept until domain is destroyed.
+     */
+    if ( (d->xenoprof == NULL) &&
+         ((ret = alloc_xenoprof_struct(d, max_samples)) < 0) )
+        goto err;
 
     xenoprof_reset_buf(d);
 
@@ -420,11 +401,11 @@ int xenoprof_init(int max_samples, xenoprof_init_result_t *init_result)
     return ret;
 }
 
-#define PRIV_OP(op) ( (op == XENOPROF_set_active) \
+#define PRIV_OP(op) ( (op == XENOPROF_set_active)       \
                    || (op == XENOPROF_reserve_counters) \
-                   || (op == XENOPROF_setup_events) \
-                   || (op == XENOPROF_start) \
-                   || (op == XENOPROF_stop) \
+                   || (op == XENOPROF_setup_events)     \
+                   || (op == XENOPROF_start)            \
+                   || (op == XENOPROF_stop)             \
                    || (op == XENOPROF_release_counters) \
                    || (op == XENOPROF_shutdown))
 
@@ -432,7 +413,7 @@ int do_xenoprof_op(int op, unsigned long arg1, unsigned long arg2)
 {
     int ret = 0;
 
-    if ( PRIV_OP(op) && current->domain != primary_profiler )
+    if ( PRIV_OP(op) && (current->domain != primary_profiler) )
     {
         printk("xenoprof: dom %d denied privileged operation %d\n",
                current->domain->domain_id, op);
@@ -468,9 +449,7 @@ int do_xenoprof_op(int op, unsigned long arg1, unsigned long arg2)
         if ( xenoprof_state != XENOPROF_COUNTERS_RESERVED )
             return -EPERM;
         if ( adomains == 0 )
-        {
             set_active_domains(0);
-        }
 
         if ( copy_from_user((void *)&counter_config, (void *)arg1, 
                             arg2 * sizeof(struct op_counter_config)) )
@@ -491,15 +470,12 @@ int do_xenoprof_op(int op, unsigned long arg1, unsigned long arg2)
         break;
 
     case XENOPROF_start:
+        ret = -EPERM;
         if ( (xenoprof_state == XENOPROF_READY) &&
              (activated == adomains) )
-        {
             ret = nmi_start();
-        }
-        else 
-            ret= -EPERM;
 
-        if ( !ret )
+        if ( ret == 0 )
             xenoprof_state = XENOPROF_PROFILING;
         break;
 
@@ -518,18 +494,19 @@ int do_xenoprof_op(int op, unsigned long arg1, unsigned long arg2)
         break;
 
     case XENOPROF_release_counters:
+        ret = -EPERM;
         if ( (xenoprof_state == XENOPROF_COUNTERS_RESERVED) ||
              (xenoprof_state == XENOPROF_READY) )
         {
             xenoprof_state = XENOPROF_IDLE;
             nmi_release_counters();
             nmi_disable_virq();
+            ret = 0;
         }
-        else
-            ret = -EPERM;
         break;
 
     case XENOPROF_shutdown:
+        ret = -EPERM;
         if ( xenoprof_state == XENOPROF_IDLE )
         {
             activated = 0;
@@ -537,8 +514,6 @@ int do_xenoprof_op(int op, unsigned long arg1, unsigned long arg2)
             primary_profiler = NULL;
             ret = 0;
         }
-        else 
-            ret = -EPERM;
         break;
 
     default:
index ccb96b0f65b362303f3454ad321d7d32050f3516..a217e1be8b2b28e59f59036c3157a28009bef7a0 100644 (file)
@@ -57,6 +57,7 @@ static int virq_is_global(int virq)
     {
     case VIRQ_TIMER:
     case VIRQ_DEBUG:
+    case VIRQ_XENOPROF:
         rc = 0;
         break;
     default:
index c79bc6f859501ec7bcc1d1a8f2560aa81bb7ca59..e18fbf96690c27b506f6f0278142cd5bbf1f0e39 100644 (file)
@@ -78,8 +78,8 @@
 #define VIRQ_CONSOLE    2  /* G. (DOM0) Bytes received on emergency console. */
 #define VIRQ_DOM_EXC    3  /* G. (DOM0) Exceptional event for some domain.   */
 #define VIRQ_DEBUGGER   6  /* G. (DOM0) A domain has paused for debugging.   */
-#define VIRQ_XENOPROF   7  /* XenOprofile interrupt: new sample available */
-#define NR_VIRQS        9
+#define VIRQ_XENOPROF   7  /* V. XenOprofile interrupt: new sample available */
+#define NR_VIRQS        8
 
 /*
  * MMU-UPDATE REQUESTS
index b8ea8a8abaf8b04dd6a7b9344de1fca0df74f091..134df887c4bd2e2d9faf4aad762fd3647fbca501 100644 (file)
@@ -48,6 +48,7 @@ typedef struct xenoprof_buf {
     uint64_t lost_samples;
     struct event_log event_log[1];
 } xenoprof_buf_t;
+DEFINE_GUEST_HANDLE(xenoprof_buf_t);
 
 typedef struct xenoprof_init_result {
     int32_t  num_events;
@@ -57,7 +58,17 @@ typedef struct xenoprof_init_result {
     uint64_t buf_maddr;
     char cpu_type[XENOPROF_CPU_TYPE_SIZE];
 } xenoprof_init_result_t;
+DEFINE_GUEST_HANDLE(xenoprof_init_result_t);
 
+typedef struct xenoprof_counter_config {
+    unsigned long count;
+    unsigned long enabled;
+    unsigned long event;
+    unsigned long kernel;
+    unsigned long user;
+    unsigned long unit_mask;
+} xenoprof_counter_config_t;
+DEFINE_GUEST_HANDLE(xenoprof_counter_config_t);
 
 #endif /* __XEN_PUBLIC_XENOPROF_H__ */
 
index 791c5665b9352dc1b3ebffee70e9e62e4bab741e..1ea48aae7dc7b0fee61841420c0d52ece3668188 100644 (file)
@@ -157,8 +157,8 @@ struct domain
     /* Control-plane tools handle for this domain. */
     xen_domain_handle_t handle;
 
-    /* pointer to xenoprof data (oprofile support) */
-    xenoprof_t *xenoprof;
+    /* OProfile support. */
+    struct xenoprof *xenoprof;
 };
 
 struct domain_setup_info
index f763eb10776b54afc5001ada8ad404c23596570b..5ecb755f42b76d71742b9046671cce3bad3541dc 100644 (file)
 #define XENOPROF_READY             2
 #define XENOPROF_PROFILING         3
 
-
-typedef struct xenoprof_vcpu {
+struct xenoprof_vcpu {
     int event_size;
-    xenoprof_buf_t *buffer;
-} xenoprof_vcpu_t;
+    struct xenoprof_buf *buffer;
+};
 
-typedef struct xenoprof {
+struct xenoprof {
     char* rawbuf;
     int npages;
     int nbuf;
@@ -34,7 +33,10 @@ typedef struct xenoprof {
     int domain_type;
     int domain_ready;
     int is_primary;
-    xenoprof_vcpu_t vcpu [MAX_VIRT_CPUS];
-} xenoprof_t;
+    struct xenoprof_vcpu vcpu [MAX_VIRT_CPUS];
+};
+
+struct domain;
+void free_xenoprof_pages(struct domain *d);
 
 #endif  /* __XEN__XENOPROF_H__ */